package com.feng.dt.util;

import com.feng.common.exception.ErrorCode;
import com.feng.common.exception.ValidationException;
import com.feng.dt.model.entity.ScheduleJob;
import com.feng.dt.quartz.job.QuartzJob;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

/**
 * @author Lee
 */
public class ScheduleUtil {

    private final static Logger LOGGER = LoggerFactory.getLogger(ScheduleUtil.class);

    private final static String JOB_KEY_PREFIX = "JOB_TASK_";

    private final static String JOB_ID_KEY = "JOB_PARAM_KEY";

    /**
     * 创建定时任务
     * @param scheduler
     * @param scheduleJob
     * @throws ValidationException
     */
    public static void createJob(Scheduler scheduler, ScheduleJob scheduleJob) throws ValidationException{

        CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
        // 1.创建job
        JobDetail job = JobBuilder.newJob(QuartzJob.class).withIdentity(JOB_KEY_PREFIX + scheduleJob.getJobId()).build();
        // 2.创建触发器
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(JOB_KEY_PREFIX + scheduleJob.getJobId())
                .withSchedule(cronSchedule)
                .build();
        // 3.创建调度器
        try {
            Objects.requireNonNull(scheduler).start();
        } catch (SchedulerException e) {
            e.printStackTrace();
            String msg = "调度任务启动失败，任务id：" + scheduleJob.getJobId();
            LOGGER.error(msg);
            throw new ValidationException(ErrorCode.SystemError,msg);
        }
        try {
            job.getJobDataMap().put(JOB_ID_KEY,scheduleJob);
            Objects.requireNonNull(scheduler).scheduleJob(job,trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
            String msg = "构建调度任务失败，任务id：" + scheduleJob.getJobId();
            LOGGER.info(msg);
            throw new ValidationException(ErrorCode.SystemError,msg);
        }

    }

    public static void updateJob(Scheduler scheduler,ScheduleJob scheduleJob)throws ValidationException{
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(JOB_KEY_PREFIX + scheduleJob.getJobId());
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
//                    错过了任务调度则不执行已经错过的
                    .withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder()
                    .withIdentity(triggerKey)
                    .withSchedule(cronScheduleBuilder)
                    .build();
            trigger.getJobDataMap().put(JOB_ID_KEY,scheduleJob.getJobId());
            scheduler.rescheduleJob(triggerKey,trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
            String msg = "调度任务更新失败，任务id：" + scheduleJob.getJobId();
            LOGGER.error(msg);
            throw new ValidationException(ErrorCode.SystemError,msg);
        }
    }

    /**
     * 暂停定时任务
     * @param scheduler
     * @param jobId
     * @throws ValidationException
     */
    public static void pauseJob(Scheduler scheduler,Integer jobId) throws ValidationException{
        try {
            scheduler.pauseJob(JobKey.jobKey(JOB_KEY_PREFIX + jobId));
        } catch (SchedulerException e) {
            e.printStackTrace();
            String msg = "调度任务暂停失败，任务id：" + jobId;
            LOGGER.error(msg);
            throw new ValidationException(ErrorCode.SystemError,msg);
        }
    }

    /**
     * 恢复定时任务
     * @param scheduler
     * @param jobId
     * @throws ValidationException
     */
    public static void resumeJob(Scheduler scheduler,Integer jobId) throws ValidationException{
        try {
            scheduler.resumeJob(JobKey.jobKey(JOB_KEY_PREFIX + jobId));
        } catch (SchedulerException e) {
            e.printStackTrace();
            String msg = String.format("恢复定时任务失败，任务id：[%s]",jobId);
            LOGGER.error(msg);
            throw new ValidationException(ErrorCode.SystemError,msg);
        }
    }

    /**
     * 删除定时任务
     * @param scheduler
     * @param jobId
     * @throws ValidationException
     */
    public static void deleteJob(Scheduler scheduler,Integer jobId) throws ValidationException{
        try {
            scheduler.deleteJob(JobKey.jobKey(JOB_KEY_PREFIX + jobId));
        } catch (SchedulerException e) {
            e.printStackTrace();
            String msg = String.format("删除定时任务失败，任务id：[%s]",jobId);
            LOGGER.error(msg);
            throw new ValidationException(ErrorCode.SystemError,msg);
        }
    }

    /**
     * 立即启动定时任务,只执行一次
     * @param scheduler
     * @param jobId
     */
    public static void run(Scheduler scheduler,Integer jobId){
        try {
//            JobDataMap jobDataMap = new JobDataMap();
//            jobDataMap.put(JOB_ID_KEY,jobId);
            scheduler.triggerJob(JobKey.jobKey(JOB_KEY_PREFIX + jobId));
        } catch (SchedulerException e) {
            e.printStackTrace();
            String msg = String.format("启动定时任务失败，任务id：[%s]",jobId);
            LOGGER.error(msg);
            throw new ValidationException(ErrorCode.SystemError,msg);
        }
    }

}
